home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / rdb / rdbflags.c < prev    next >
C/C++ Source or Header  |  1996-02-04  |  8KB  |  282 lines

  1. /*
  2.  * modify RDB flags
  3.  *
  4.  * Copyright © 1994 by Andreas M. Kirchwitz
  5.  *                     Seesener Straße 69
  6.  *                     D-10709 Berlin, Germany
  7.  *                     UUCP/Internet: amk@zikzak.in-berlin.de
  8.  *
  9.  * Thanks to Ralph Babel (author of "The Amiga Guru Book")
  10.  * and Matthias Scheler (owner of a copy of "The Amiga Guru Book").
  11.  */
  12.  
  13. #define __USE_SYSBASE
  14.  
  15. #include <exec/types.h>
  16. #include <exec/alerts.h>
  17. #include <exec/memory.h>
  18. #include <devices/trackdisk.h>
  19. #include <devices/hardblocks.h>
  20. #include <dos/dosextens.h>
  21. #include <dos/rdargs.h>
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24.  
  25. extern struct ExecBase *__far AbsExecBase;
  26.  
  27. /* defines */
  28.  
  29. #define PROGRAMNAME_MAX 32
  30.  
  31. #define DEFAULT_DEVICE        "scsi.device"
  32. #define DEFAULT_UNIT        0
  33. #define DEFAULT_SECTORSIZE    TD_SECTOR
  34. #define DEFAULT_FLAGS        0
  35.  
  36. #define RDBFLAGS_TEMPLATE "Device/K,Unit/N,SectorSize/N,LastDisk/S,NoLastDisk/S,LastLun/S,NoLastLun/S,LastTarget/S,NoLastTarget/S,Reselect/S,NoReselect/S,Sync/S,NoSync/S"
  37.  
  38. struct Args
  39. {
  40.     char *device;
  41.     LONG *pUnit;
  42.     LONG *pSectorSize;
  43.     LONG lastDisk;
  44.     LONG noLastDisk;
  45.     LONG lastLun;
  46.     LONG noLastLun;
  47.     LONG lastTarget;
  48.     LONG noLastTarget;
  49.     LONG reselection;
  50.     LONG noReselection;
  51.     LONG synchronous;
  52.     LONG noSynchronous;
  53.     LONG defaultUnit;
  54.     LONG defaultSectorSize;
  55. };
  56.  
  57. /* globals */
  58.  
  59. static const char version[] = "$VER: RDBFlags 1.3 " __AMIGADATE__;
  60.  
  61. LONG main(void)
  62. {
  63.     LONG result;
  64.     struct ExecBase *SysBase;
  65.     struct Library *DOSBase;
  66.     struct Process *pr;
  67.     struct Message *mn;
  68.     struct RDArgs *rda;
  69.     struct MsgPort *mp;
  70.     struct IOStdReq *io;
  71.     struct RigidDiskBlock *rdb;
  72.     char *name;
  73.     char *device;
  74.     ULONG unit;
  75.     ULONG sectorSize, i;
  76.     ULONG sector;
  77.     ULONG flags;
  78.     LONG *p, sum;
  79.     struct Args args;
  80.     struct DriveGeometry DG;
  81.     char programName[PROGRAMNAME_MAX];
  82.  
  83.     SysBase = AbsExecBase;
  84.  
  85.     pr = (struct Process *) FindTask(NULL);
  86.  
  87.     result = RETURN_FAIL;
  88.  
  89.     if (pr->pr_CLI != NULL)
  90.     {
  91.         if ((DOSBase = OpenLibrary(DOSNAME, 37)) != NULL)
  92.         {
  93.             if (!GetProgramName(name = programName, PROGRAMNAME_MAX))
  94.                 name = "RDBFlags";
  95.  
  96.             args.device            = DEFAULT_DEVICE;
  97.             args.pUnit             = &args.defaultUnit;
  98.             args.pSectorSize       = &args.defaultSectorSize;
  99.             args.lastDisk          = FALSE;
  100.             args.noLastDisk        = FALSE;
  101.             args.lastLun           = FALSE;
  102.             args.noLastLun         = FALSE;
  103.             args.lastTarget        = FALSE;
  104.             args.noLastTarget      = FALSE;
  105.             args.reselection       = FALSE;
  106.             args.noReselection     = FALSE;
  107.             args.synchronous       = FALSE;
  108.             args.noSynchronous     = FALSE;
  109.             args.defaultUnit       = DEFAULT_UNIT;
  110.             args.defaultSectorSize = DEFAULT_SECTORSIZE;
  111.  
  112.             if (rda = ReadArgs(RDBFLAGS_TEMPLATE, (LONG *) &args, NULL))
  113.             {
  114.                 device = args.device;
  115.                 unit   = *args.pUnit;
  116.  
  117.                 result = RETURN_ERROR;
  118.  
  119.                 if ((mp = CreateMsgPort()) != NULL)
  120.                 {
  121.                     if ((io = CreateIORequest(mp, sizeof(struct IOStdReq))) != NULL)
  122.                     {
  123.                         if (OpenDevice(device, unit, (struct IORequest *) io, DEFAULT_FLAGS) == 0)
  124.                         {
  125.                             Printf("device \"%s\", unit %lu\n", device, unit);
  126.  
  127.                             io->io_Command = TD_GETGEOMETRY;
  128.                             io->io_Length  = sizeof(struct DriveGeometry);
  129.                             io->io_Data    = &DG;
  130.  
  131.                             if (DoIO((struct IORequest *) io) != 0) {
  132.                                 Printf("%s: error %ld while reading drive geometry.\n", name, (LONG) io->io_Error);
  133.                                 Printf("%s: (use option \"SectorSize\" to override default sector size)\n", name);
  134.                                 DG.dg_SectorSize = *args.pSectorSize;
  135.                                 DG.dg_BufMemType = MEMF_CHIP;
  136.                             }
  137.                             else if (args.pSectorSize != &args.defaultSectorSize) {
  138.                                 DG.dg_SectorSize = *args.pSectorSize;
  139.                                 DG.dg_BufMemType = MEMF_CHIP;
  140.                             }
  141.  
  142.                             sectorSize = DG.dg_SectorSize;
  143.  
  144.                             Printf("sector size is %lu bytes\n", sectorSize);
  145.  
  146.                             if (sectorSize >= sizeof(struct RigidDiskBlock))
  147.                             {
  148.                                 if (rdb = AllocMem(sectorSize, DG.dg_BufMemType))
  149.                                 {
  150.                                     for (sector = 0; sector < RDB_LOCATION_LIMIT; ++sector)
  151.                                     {
  152.                                         io->io_Command = CMD_READ;
  153.                                         io->io_Length  = sectorSize;
  154.                                         io->io_Data    = rdb;
  155.                                         io->io_Offset  = sector * sectorSize;
  156.  
  157.                                         if (DoIO((struct IORequest *) io) == 0
  158.                                             && rdb->rdb_ID == IDNAME_RIGIDDISK
  159.                                             && rdb->rdb_SummedLongs * sizeof(LONG) <= sectorSize)
  160.                                         {
  161.                                             for (sum = 0, p = (LONG *) rdb, i = rdb->rdb_SummedLongs; i != 0; --i)
  162.                                                 sum += *p++;
  163.  
  164.                                             if (sum == 0 && rdb->rdb_BlockBytes == sectorSize)
  165.                                                 break;
  166.                                         }
  167.                                     }
  168.  
  169.                                     if (sector != RDB_LOCATION_LIMIT)
  170.                                     {
  171.                                         Printf("found RDB at sector %lu\n", sector);
  172.                                         Printf("drive %-.8s %-.16s %-.4s\n", rdb->rdb_DiskVendor, rdb->rdb_DiskProduct, rdb->rdb_DiskRevision);
  173.  
  174.                                         flags = rdb->rdb_Flags;
  175.  
  176.                                         if ( args.lastDisk    && args.noLastDisk
  177.                                           || args.lastLun     && args.noLastLun
  178.                                           || args.lastTarget  && args.noLastTarget
  179.                                           || args.reselection && args.noReselection
  180.                                           || args.synchronous && args.noSynchronous )
  181.                                         {
  182.                                             Printf("%s: contradictory options, won't alter RDB.\n", name);
  183.                                         }
  184.                                         else
  185.                                         {
  186.                                             if (args.lastDisk)      flags |=  RDBFF_LAST;
  187.                                             if (args.noLastDisk)    flags &= ~RDBFF_LAST;
  188.                                             if (args.lastLun)       flags |=  RDBFF_LASTLUN;
  189.                                             if (args.noLastLun)     flags &= ~RDBFF_LASTLUN;
  190.                                             if (args.lastTarget)    flags |=  RDBFF_LASTTID;
  191.                                             if (args.noLastTarget)  flags &= ~RDBFF_LASTTID;
  192.                                             if (args.reselection)   flags &= ~RDBFF_NORESELECT;
  193.                                             if (args.noReselection) flags |=  RDBFF_NORESELECT;
  194.                                             if (args.synchronous)   flags |=  RDBFF_SYNCH;
  195.                                             if (args.noSynchronous) flags &= ~RDBFF_SYNCH;
  196.                                         }
  197.  
  198.                                         Printf("\n last disk:   %s\n", flags & RDBFF_LAST       ? "yes" : "no");
  199.                                         Printf(" last lun:    %s\n",   flags & RDBFF_LASTLUN    ? "yes" : "no");
  200.                                         Printf(" last target: %s\n",   flags & RDBFF_LASTTID    ? "yes" : "no");
  201.                                         Printf(" reselection: %s\n",   flags & RDBFF_NORESELECT ? "no"  : "yes");
  202.                                         Printf(" synchronous: %s\n\n", flags & RDBFF_SYNCH      ? "yes" : "no");
  203.  
  204.                                         result = RETURN_OK;
  205.  
  206.                                         if (flags != rdb->rdb_Flags)
  207.                                         {
  208.                                             rdb->rdb_Flags = flags;
  209.  
  210.                                             rdb->rdb_ChkSum = 0;
  211.                                             for (sum = 0, p = (LONG *) rdb, i = rdb->rdb_SummedLongs; i != 0; --i)
  212.                                                 sum -= *p++;
  213.                                             rdb->rdb_ChkSum = sum;
  214.  
  215.                                             Printf("RDB modified, saving to disk!\n");
  216.  
  217.                                             io->io_Command = CMD_WRITE;
  218.                                             io->io_Length  = sectorSize;
  219.                                             io->io_Data    = rdb;
  220.                                             io->io_Offset  = sector * sectorSize;
  221.  
  222.                                             if (DoIO((struct IORequest *) io) == 0)
  223.                                             {
  224.                                                 io->io_Command = CMD_UPDATE;
  225.                                                 (void) DoIO((struct IORequest *) io);
  226.                                             }
  227.  
  228.                                             if (io->io_Error != 0)
  229.                                             {
  230.                                                 result = RETURN_ERROR;
  231.                                                 io->io_Command = CMD_CLEAR;
  232.                                                 (void) DoIO((struct IORequest *) io);
  233.                                                 Printf("%s: error %ld while writing RDB.\n", name, (LONG) io->io_Error);
  234.                                             }
  235.                                         }
  236.                                     }
  237.                                     else
  238.                                         Printf("%s: no RDB found.\n", name);
  239.  
  240.                                     io->io_Command = TD_MOTOR;
  241.                                     io->io_Length  = 0;
  242.                                     (void) DoIO((struct IORequest *) io);
  243.  
  244.                                     FreeMem(rdb, sectorSize);
  245.                                 }
  246.                                 else
  247.                                     PrintFault(ERROR_NO_FREE_STORE, name);
  248.                             }
  249.                             else
  250.                                 Printf("%s: sector size %lu too small for RDB.\n", name, sectorSize);
  251.  
  252.                             CloseDevice((struct IORequest *) io);
  253.                         }
  254.                         else
  255.                             Printf("%s: error %ld opening \"%s\", unit %lu.\n", name, (LONG) io->io_Error, device, unit);
  256.  
  257.                         DeleteMsgPort(mp);
  258.                     }
  259.                     DeleteIORequest(io);
  260.                 }
  261.                 FreeArgs(rda);
  262.             }
  263.             else
  264.                 PrintFault(IoErr(), name);
  265.  
  266.             CloseLibrary(DOSBase);
  267.         }
  268.         else
  269.             Alert(AT_Recovery | AG_OpenLib | AO_DOSLib);
  270.     }
  271.     else
  272.     {
  273.         (void) WaitPort(&pr->pr_MsgPort);
  274.         mn = GetMsg(&pr->pr_MsgPort);
  275.         Forbid();
  276.         ReplyMsg(mn);
  277.     }
  278.  
  279.     return result;
  280. }
  281.  
  282.